package org.objective.base;

import org.objective.service.LoadingException;
import org.objective.service.Loader;
import org.objective.service.Saver;
import java.util.UUID;
import org.objective.ddl.type.DDLConstants;

/**
 *
 * @author gus
 */
public abstract class BaseObject extends BaseDomainObject implements Storable
{
    private final BaseObject owner;
    private final BaseType type;
    private final ObjectCollection<BaseField, BaseObject> fields;
    private final ObjectCollection<BaseView, BaseObject>  views;
    private String description;
    private String objectName;

    protected BaseObject(Storage storage, long id, BaseType type, BaseObject owner) throws Exception
    {
        super(storage, id);
        this.owner = owner;
        this.type = type;
        this.uid = UUID.randomUUID();
        this.fields = createFieldCollection();
        this.views =  createViewCollection();
        createDefaultContent();
    }

    public String getObjectName()
    {
        return objectName;
    }

    public void setObjectName(String name)
    {
        this.objectName = name;
    }

    public BaseType getType()
    {
        return type;
    }


    public BaseObject getOwner()
    {
        return owner;
    }

    public ObjectCollection<? extends BaseField, BaseObject> getFields()
    {
        return fields;
    }

    public ObjectCollection<? extends BaseView, BaseObject> getViews()
    {
        return views;
    }

    @Override
    public void loadData(Loader loader) throws Exception
    {
        BaseObjectInfo objectInfo = loader.getObject(id);
        if (objectInfo == null)
        {
            throw new LoadingException(id);
        }
        objectName = objectInfo.getObjectName();
        description = objectInfo.getDescription();
        uid = objectInfo.getUid();
        loadFields(loader);
    }

    @Override
    public Storable[] loadDepends()
    {
        return new Storable[0];
    }

    @Override
    public void saveData(Saver saver) throws Exception
    {
        BaseObjectInfo objectInfo = new BaseObjectInfo();
        objectInfo.setId(id);
        objectInfo.setUid(uid);
        objectInfo.setDescription(description);
        objectInfo.setObjectName(objectName);
        objectInfo.setOwner(owner != null ? owner.getID() : DDLConstants.NullValue.ID);
        saver.insertObject(objectInfo);

        saveFields(saver);

    }

    @Override
    public Storable[] saveDepends()
    {
        return new Storable[0];
    }

    protected abstract void createDefaultContent() throws Exception;

    protected abstract ObjectCollection<BaseField, BaseObject> createFieldCollection();
    protected abstract ObjectCollection<BaseView, BaseObject> createViewCollection();

    private void saveFields(Saver saver) throws Exception
    {
        for (BaseField field : fields)
        {
            for (Storable storable : field.saveDepends())
            {
                storable.saveData(saver);
            }
            field.saveData(saver);
        }
    }

    private void loadFields(Loader loader) throws Exception
    {
        long[] fieldIdList = loader.loadFieldIDList(id);
        try
        {
            fields.load(loader, fieldIdList);
        }
        catch (Exception exc)
        {
            throw new LoadingException(id);
        }
    }
}
